package org.chen.ctrip.service.ollama;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
public class ItineraryExtractorService {

    @Value("${flowise.base-url}")
    private String ollamaBaseUrl;

    private final RestTemplate restTemplate = new RestTemplate();
    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 提取第一天的行程内容
     */
    public String extractFirstDayContent(String pageDiv) {
        try {
            Document doc = Jsoup.parse(pageDiv);
            
            // 查找第一个包含Day的table
            Elements tables = doc.select("table.print_table");
            for (Element table : tables) {
                Elements dayHeaders = table.select("th:contains(Day)");
                if (!dayHeaders.isEmpty()) {
                    String dayText = dayHeaders.first().text();
                    // 检查是否是第一天（Day 01 或 Day 1）
                    if (dayText.contains("Day") && (dayText.contains("01") || dayText.contains("1"))) {
                        return extractTableContent(table);
                    }
                }
            }
            
            // 如果找不到，返回第一个table的内容
            if (!tables.isEmpty()) {
                return extractTableContent(tables.first());
            }
            
            return "未找到第一天行程内容";
        } catch (Exception e) {
            log.error("提取第一天行程内容失败: {}", e.getMessage(), e);
            return "提取第一天行程内容失败";
        }
    }

    /**
     * 提取最后一天的行程内容
     */
    public String extractLastDayContent(String pageDiv) {
        try {
            Document doc = Jsoup.parse(pageDiv);
            
            // 查找所有包含Day的table，找到最大的天数
            Elements tables = doc.select("table.print_table");
            Element lastDayTable = null;
            int maxDay = 0;
            
            for (Element table : tables) {
                Elements dayHeaders = table.select("th:contains(Day)");
                if (!dayHeaders.isEmpty()) {
                    String dayText = dayHeaders.first().text();
                    int dayNumber = extractDayNumber(dayText);
                    if (dayNumber > maxDay) {
                        maxDay = dayNumber;
                        lastDayTable = table;
                    }
                }
            }
            
            if (lastDayTable != null) {
                return extractTableContent(lastDayTable);
            }
            
            // 如果找不到，返回最后一个table的内容
            if (!tables.isEmpty()) {
                return extractTableContent(tables.last());
            }
            
            return "未找到最后一天行程内容";
        } catch (Exception e) {
            log.error("提取最后一天行程内容失败: {}", e.getMessage(), e);
            return "提取最后一天行程内容失败";
        }
    }

    /**
     * 从table中提取完整的行程内容
     */
    private String extractTableContent(Element table) {
        StringBuilder content = new StringBuilder();
        
        try {
            // 提取表头（天数信息）
            Elements headers = table.select("th");
            for (Element header : headers) {
                String headerText = header.text().trim();
                if (!headerText.isEmpty()) {
                    content.append("=== ").append(headerText).append(" ===\n\n");
                }
            }
            
            // 提取所有行内容
            Elements rows = table.select("tr");
            for (Element row : rows) {
                // 跳过表头行
                if (row.select("th").size() > 0) {
                    continue;
                }
                
                Elements cells = row.select("td");
                if (cells.size() >= 2) {
                    // 时间信息
                    Element timeCell = cells.get(0);
                    String time = timeCell.select("p.print_table_time").text().trim();
                    
                    // 活动内容
                    Element contentCell = cells.get(1);
                    String title = contentCell.select("p.print_table_title").text().trim();
                    String description = contentCell.select("div.print_table_td_text").text().trim();
                    
                    if (!time.isEmpty() || !title.isEmpty()) {
                        if (!time.isEmpty()) {
                            content.append("【时间】").append(time).append("\n");
                        }
                        if (!title.isEmpty()) {
                            content.append("【活动】").append(title).append("\n");
                        }
                        if (!description.isEmpty() && description.length() > 10) {
                            // 限制描述长度，避免内容过长
                            String shortDesc = description.length() > 500 ? 
                                description.substring(0, 500) + "..." : description;
                            content.append("【详情】").append(shortDesc).append("\n");
                        }
                        content.append("\n");
                    }
                }
            }
            
            return content.toString().trim();
        } catch (Exception e) {
            log.error("提取表格内容失败: {}", e.getMessage(), e);
            return table.text(); // 降级处理，返回纯文本
        }
    }

    /**
     * 从文本中提取天数数字
     */
    private int extractDayNumber(String dayText) {
        try {
            // 提取Day后面的数字
            Pattern pattern = Pattern.compile("Day\\s*(?:<!--\\s*-->)?\\s*(\\d+)", Pattern.CASE_INSENSITIVE);
            Matcher matcher = pattern.matcher(dayText);
            if (matcher.find()) {
                return Integer.parseInt(matcher.group(1));
            }
            return 0;
        } catch (Exception e) {
            return 0;
        }
    }

    /**
     * 清理和转义文本内容，防止JSON解析错误
     */
    private String cleanContentForJson(String content) {
        if (content == null) {
            return "";
        }

        // 移除或替换可能导致JSON解析问题的字符
        return content
                // 移除控制字符
                .replaceAll("[\\x00-\\x1F\\x7F]", "")
                // 处理特殊的Unicode字符
                .replaceAll("[\uFEFF\u200B\u200C\u200D]", "")
                // 移除过多的连续空格
                .replaceAll("\\s+", " ")
                // 移除可能的HTML残留
                .replaceAll("<[^>]*>", "")
                // 替换双引号为单引号，避免JSON解析错误
                .replaceAll("\"", "'")
                .trim();
    }
    
    /**
     * 调用本地Ollama进行内容总结
     */
    public String summarizeWithOllama(String content) {
        try {
            // 清理内容，防止JSON解析错误
            String cleanedContent = cleanContentForJson(content);

            // 构建请求体
            Map<String,Object> requestBody = new HashMap<>();

            List<String> questions = new ArrayList<>();
            questions.add(cleanedContent);

            // 先把问题列表转换为 JSON 字符串
            String questionJson = objectMapper.writeValueAsString(questions);  // 变成 "[\"1\",\"2\"]"

            requestBody.put("question", questionJson); // 注意是字符串
            requestBody.put("chatId", "565b3b46-9bbf-4500-bb53-989f486ffcd6");
            requestBody.put("overrideConfig", new HashMap<>());
            requestBody.put("stream", false);

            log.info("调用Ollama参数：{}", requestBody);
            
            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Accept", "application/json");

            String jsonBody = objectMapper.writeValueAsString(requestBody);

            HttpEntity<String> request = new HttpEntity<>(jsonBody, headers);
            
            // 发送请求到Ollama
            String url = ollamaBaseUrl;
            ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
            
            if (response.getStatusCode() == HttpStatus.OK) {
                JsonNode responseJson = objectMapper.readTree(response.getBody());
                return responseJson.get("text").asText();
            } else {
                log.error("Ollama请求失败，状态码: {}", response.getStatusCode());
                return "AI总结失败：服务响应异常";
            }
            
        } catch (Exception e) {
            log.error("调用Ollama进行总结失败: {}", e.getMessage(), e);
            return "AI总结失败：" + e.getMessage();
        }
    }

    /**
     * 处理第一天行程并生成总结
     */
    public String processFirstDay(String pageDiv) {
        String firstDayContent = extractFirstDayContent(pageDiv);
        if (firstDayContent.contains("未找到") || firstDayContent.contains("失败")) {
            return firstDayContent;
        }

        return summarizeWithOllama(firstDayContent);
    }

    /**
     * 处理最后一天行程并生成总结
     */
    public String processLastDay(String pageDiv) {
        String lastDayContent = extractLastDayContent(pageDiv);
        if (lastDayContent.contains("未找到") || lastDayContent.contains("失败")) {
            return lastDayContent;
        }

        return summarizeWithOllama(lastDayContent);
    }
}